package com.bestcem.xm.qdes.controller;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.annotation.XmGet;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.qdes.controller.param.GetPublishRecordParam;
import com.bestcem.xm.qdes.controller.param.QuestionRestNoParam;
import com.bestcem.xm.qdes.controller.vo.DeletedCountVo;
import com.bestcem.xm.qdes.controller.vo.OnlyIdVo;
import com.bestcem.xm.qdes.controller.vo.QstructsDetailVo;
import com.bestcem.xm.qdes.entity.QdesProject;
import com.bestcem.xm.qdes.entity.QdesQstruct;
import com.bestcem.xm.qdes.entity.QdesQuestion;
import com.bestcem.xm.qdes.service.QdesQstructService;
import com.bestcem.xm.qdes.service.QdesQuestionLibService;
import com.bestcem.xm.qdes.service.QdesQuestionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

import static com.bestcem.xm.common.core.enums.ReqErrorCodeEnum.PARAM_LOST;
import static com.bestcem.xm.qdes.util.QstructConstant.*;

@Slf4j
@Api(tags = "问卷编辑-问卷结构qstructs")
@RestController
@RequiredArgsConstructor
@RequestMapping("/qdes/qstructs")
public class ProjectQstructsController {

    private @NonNull QdesQuestionLibService questionlibService;

    private @NonNull QdesQuestionService questionService;

    private @NonNull QdesQstructService qstructService;

    /**
     * 题目库-题目详情查询/题目列表查询
     * withQ=1&timemap=1660122348378
     *
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataTypeClass = String.class, name = "id", value = "主键"),
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "withQ", value = "withQ"),
            @ApiImplicitParam(paramType = "query", dataTypeClass = String.class, name = "timeMap", value = "时间戳")
    })
    @ApiOperation(value = "题目库-题目详情查询/题目列表查询", httpMethod = "GET")
    @GetMapping("/{id:[a-fA-F0-9]{24}}")
    public XmResultJson<QstructsDetailVo> qstructsDetail(@PathVariable String id, @RequestParam(value = "withQ", required = false) String withQ, @RequestParam(value = "timemap", required = false) String timeMap) {
        return XmResultJson.success(questionlibService.qstructsDetail(id, withQ, timeMap));
    }

    /**
     * {"id":"6323f3083e2c0c000878b502","cid":"Q111","gid":6,"seq":6,"type":"Q","align":"vertical","fixed":false,"items":[{"gid":7,"oid":1,"seq":7,"type":"O","title":"选项1","is_open":false,"disp_code":"","exclusive":false,"open_attrs":{"type":0,"unit":"","range":[],"unique":"none","required":true},"plaster_code":""},{"gid":8,"oid":2,"seq":8,"type":"O","title":"选项2","is_open":false,"disp_code":"","exclusive":false,"open_attrs":{"type":0,"unit":"","range":[],"unique":"none","required":true},"plaster_code":""},{"gid":21,"oid":3,"seq":21,"type":"O","title":"选项3","is_open":false,"disp_code":"","exclusive":false,"open_attrs":{"type":0,"unit":"","range":[],"unique":"none","required":true},"plaster_code":"","pos":"after","prevGid":8,"forbidRelated":false},{"gid":22,"oid":4,"seq":22,"type":"O","title":"选项4","is_open":false,"disp_code":"","exclusive":false,"open_attrs":{"type":0,"unit":"","range":[],"unique":"none","required":true},"plaster_code":"","pos":"after","prevGid":21,"forbidRelated":false}],"qtype":"multiple","title":"多选题11","_index":1,"required":true,"disp_code":"","jump_code":"","codeSelect":true,"group_align":"vertical","column_value":2,"custom_qtype":"multiple","vote_setting":false,"options_range":[0,0],"options_random":false,"option_bind_list":[],"option_group_list":[],"optionsBindEffect":false,"default_q_timecost":2,"optionsGroupEffect":false,"defaultOptionSelect":0,"option_exclude_list":[],"optionsExcludeEffect":false,"options_group_random":false}
     * {"code": 0, "data": {}}
     *
     * @param id
     * @param gid
     * @param param
     * @return com.bestcem.xm.common.core.domain.web.XmResultJson<java.lang.Object>
     * @author chenglong.yue <chenglong.yue@idiaoyan.com>
     * @date 2022/9/16 17:42
     */
    @ApiOperation(value = "单个题目修改")
    @PutMapping("/{id:[a-fA-F0-9]{24}}/questions/{gid:\\d+}")
    public XmResultJson<Object> updateOneQuestion(@PathVariable String id, @PathVariable String gid, @RequestBody JSONObject param) {
        log.info("updateOneQuestion qstructid:{},bodyparam:{}", id, param.toJSONString());
        questionService.checkCid(param);
        questionService.checkOid(param);
        QdesQstruct struct = questionService.checkAndGetQstruct(id);
        QdesQuestion question = questionService.checkAndGetQuestion(id, gid);

        questionService.checkOptionsGroupEffect(param, struct, id, gid);
        questionService.checkOptionOrigin(param, question, id, gid);

        param.put(GID, Integer.valueOf(gid));
        param.put(SEQ, Integer.valueOf(gid));
        questionService.updateQuestion(id, gid, param, question, struct);
        return XmResultJson.success(new JSONObject());
    }


    @ApiOperation(value = "问卷大纲-批量更新题目")
    @PutMapping("/{id:[a-fA-F0-9]{24}}/questions/")
    public XmResultJson<Object> updateQuestionList(@PathVariable String id, @RequestBody JSONArray param) {
        log.info("updateQuestionList qstructid:{},bodyparam:{}", id, param.toJSONString());
        int count = param.size();
        List<String> gids = new ArrayList<>();
        List<JSONObject> datas = new ArrayList<>();
        List<QdesQuestion> questions = new ArrayList<>();

        QdesQstruct struct = questionService.checkAndGetQstruct(id);
        // 验证参数合法性，并组装list
        for (int i = 0; i < count; i++) {
            JSONObject data = param.getJSONObject(i);
            String gid = data.getString(GID);
            data.put(SEQ, Integer.valueOf(gid));

            questionService.checkCid(data);
            questionService.checkOid(data);
            QdesQuestion question = questionService.checkAndGetQuestion(id, gid);

            questionService.checkOptionsGroupEffect(data, struct, id, gid);
            questionService.checkOptionOrigin(data, question, id, gid);

            gids.add(gid);
            datas.add(data);
            questions.add(question);
        }
        questionService.updateQuestions(id, gids, datas, questions, struct, count);
        return XmResultJson.success(new JSONObject());
    }

    /**
     * 单选题示例：{"type":"Q","gid":138,"cid":"Q5","align":"vertical","options_random":false,"required":true,"title":"单选题","qtype":"single","custom_qtype":"single","column_value":2,"vote_setting":false,"answerStyle":"custom","disp_code":"","fixed":false,"items":[{"type":"O","gid":139,"title":"选项1","seq":139,"oid":1,"is_open":false,"disp_code":"","plaster_code":"","open_attrs":{"required":true,"type":0,"range":[],"unique":"none","unit":""}},{"type":"O","gid":140,"title":"选项2","seq":140,"oid":2,"is_open":false,"disp_code":"","plaster_code":"","open_attrs":{"required":true,"type":0,"range":[],"unique":"none","unit":""}}],"codeSelect":true,"jump_code":"","option_bind_list":[],"optionsBindEffect":false,"option_group_list":[],"optionsGroupEffect":false,"_index":5,"defaultOptionSelect":0,"options_group_random":false,"group_align":"vertical"}
     * 返回值示例： {"code": 0, "data": {}}
     * 问卷大纲可以批量复制
     *
     * @param id
     * @param param
     * @return com.bestcem.xm.common.core.domain.web.XmResultJson<java.lang.Object>
     * @author chenglong.yue <chenglong.yue@idiaoyan.com>
     * @date 2022/9/9 17:11
     */
    @ApiOperation(value = "题型选择-添加题目")
    @PostMapping("/{id:[a-fA-F0-9]{24}}/questions/")
    public XmResultJson<Object> addQuestion(@PathVariable String id, @RequestBody String param) {
        log.info("addQuestion qstructid:{},bodyparam:{}", id, param);
        if (JSONUtil.isTypeJSONArray(param)) {
            JSONArray array = JSON.parseArray(param);
            for (int i = 0; i < array.size(); i++) {
                JSONObject oneparam = array.getJSONObject(i);
                if (!oneparam.containsKey(GID)) {
                    return XmResultJson.fail(PARAM_LOST, "gid 是必要参数");
                }
                questionService.checkCid(oneparam);

                questionService.addOneQuestion(id, oneparam);
            }
        } else {
            JSONObject oneparam = JSON.parseObject(param);
            if (!oneparam.containsKey(GID)) {
                return XmResultJson.fail(PARAM_LOST, "gid 是必要参数");
            }
            questionService.checkCid(oneparam);

            questionService.addOneQuestion(id, oneparam);
        }
        return XmResultJson.success(new JSONObject());
    }


    /**
     * {"gid_list":[2,6]} => {"code": 0, "data": {"deletedCount": 2}}
     *
     * @param id
     * @param param
     * @return
     */
    @ApiOperation(value = "问卷大纲-批量删除题目")
    @DeleteMapping("/{id:[a-fA-F0-9]{24}}/questions/")
    public XmResultJson<DeletedCountVo> delQuestions(@PathVariable String id, @RequestBody JSONObject param) {
        log.info("delQuestions qstructId:{},bodyparam:{}", id, param.toJSONString());
        if (!param.containsKey(GID_LIST)) {
            return XmResultJson.fail(PARAM_LOST, "参数不合法，没有gid_list");
        }
        int count = questionService.delQuestions(id, param);
        DeletedCountVo deletedCountVo = new DeletedCountVo();
        deletedCountVo.setDeletedCount(count);
        return XmResultJson.success(deletedCountVo);
    }

    /**
     * => {"code": 0, "data": {"deletedCount": 2}}
     *
     * @param id
     * @param gid
     * @return com.bestcem.xm.common.core.domain.web.XmResultJson<java.lang.Object>
     * @author chenglong.yue <chenglong.yue@idiaoyan.com>
     * @date 2022/9/13 17:34
     */
    @ApiOperation(value = "删除一个题目")
    @DeleteMapping("/{id:[a-fA-F0-9]{24}}/questions/{gid:\\d+}")
    public XmResultJson<DeletedCountVo> delOneQuestion(@PathVariable String id, @PathVariable String gid) {
        log.info("delOneQuestion qstructId:{},gid:{}", id, gid);
        int count = questionService.delOneQuestion(id, gid);
        DeletedCountVo deletedCountVo = new DeletedCountVo();
        deletedCountVo.setDeletedCount(count);
        return XmResultJson.success(deletedCountVo);
    }

    /**
     * {"structID":"631ae1743e2c0c000978b0d0","gids":[8,135]} =>{"code": 0, "data": 2}
     *
     * @param param
     * @return com.bestcem.xm.common.core.domain.web.XmResultJson<java.lang.Integer>
     * @author chenglong.yue <chenglong.yue@idiaoyan.com>
     * @date 2022/9/16 11:50
     */
    @ApiOperation(value = "问卷编辑-重置题目编号")
    @PutMapping("/questions/reset/")
    public XmResultJson<Integer> questionResetNo(@Validated @RequestBody QuestionRestNoParam param) {
        log.info("questionResetNo bodyparam:{}", JSONUtil.toJsonStr(param));
        QdesQstruct struct = questionService.checkAndGetQstruct(param.getStructId());
        return XmResultJson.success(questionService.resetQuestionNo(struct, param));
    }


    /**
     * 更新问卷结构
     * {"data":{"type":"G","items":[{"cid":"P1","gid":5,"logo":{},"type":"G","items":[{"_index":1,"gid":2},{"_index":2,"gid":7},{"_index":3,"gid":12},{"_index":4,"gid":18},{"_index":5,"gid":21},{"_index":6,"gid":24}],"_index":1,"bg_img":{},"show_page":1,"stems_font":{},"page_header":{},"options_font":{}}],"groups":{"0":{"data":[{"cid":"G0","gid":1,"sort":0,"type":"G","fixed":false,"title":"题目","disp_code":"","mergePage":false,"pGroupGid":0}],"sorts":[{"gid":1,"type":"G"}]}},"version":"","survey_id":"","answerRefs":{},"ext_params":{},"relatedRefs":{"18":[{"mode":"select","type":"O","maxLevel":1,"sourceGid":12,"targetGid":18}]},"select_view":"phone","dispConsList":[],"jumpConsList":[],"desc_end_page":{"logo":{"img":{"logo_scale":100},"position":"left"},"bg_img":{"img":{},"type":"img","color":"#303133","fillStyle":"fill","base_color":"#fff"},"content":{"font":{"css":"font-size: 16px;color: #606266;","size":12,"color":"#606266","is_bold":false,"is_italic":false,"is_underline":false},"text":"<p style=\"text-align:center;\"><img class=\"q-default__img\" src=\"/statics/editor/pc/default/end_page.png\" /></p><br /><p style=\"text-align:center;\">您已完成本次问卷，感谢您的帮助与支持</p>","jumpLink":"","protocol":"https://","phone_font":{"css":"font-size: 16px;color: #606266;","size":12,"color":"#606266","is_bold":false,"is_italic":false,"is_underline":false},"quota_full":"<p style=\"text-align:center;\"><img class=\"end-img\" src=\"/statics/editor/pc/default/404_quotafull.png\" /></p><br /><p style=\"text-align:center;\">对不起，您不属于本次调查的范围。谢谢您的参与！</p>","screen_out":"<p style=\"text-align:center;\"><img class=\"end-img\" src=\"/statics/editor/pc/default/404_overflow.png\" /></p><br /><p style=\"text-align:center;\">对不起，您不属于本次调查的范围。谢谢您的参与！</p>","selectType":0},"phone_logo":{"img":{"logo_scale":100},"position":"left"},"phone_bg_img":{"img":{},"type":"img","color":"#fff","fillStyle":"fill","base_color":"#fff"}},"selectedTheme":"default","usedColorList":[],"desc_begin_page":{"desc":{"text":"<p style=\"text-align:center;\">感谢您能抽出几分钟时间来参加本次答题，现在我们就马上开始吧！</p>"},"logo":{"img":{"logo_scale":100},"position":"left"},"bg_img":{"img":{},"type":"img","color":"#303133","fillStyle":"fill","base_color":"#fff"},"content":{"font":{"css":"font-size: 14px;color: #909399;","size":14,"color":"#909399","is_bold":false,"is_italic":false,"is_underline":false},"text":"<p style=\"text-align:center;\">ssss</p>","phone_font":{"css":"font-size: 14px;color: #909399;","size":14,"color":"#909399","is_bold":false,"is_italic":false,"is_underline":false},"showStartPage":false,"phone_showStartPage":false},"start_btn":{"font":{"css":"font-size: 16px;color: #fff;","size":14,"color":"#fff","is_bold":false,"is_italic":false,"is_underline":false},"bg_color":""},"phone_logo":{"img":{"logo_scale":100},"position":"left"},"open_policy":false,"page_header":{"img":{"filePath":"/statics/editor/pc/default/start_page.png"}},"policy_desc":"我已阅读并同意[用户协议]和[隐私协议]","phone_bg_img":{"img":{},"type":"img","color":"#fff","fillStyle":"fill","base_color":"#fff"},"phone_start_btn":{"font":{"css":"font-size: 16px;color: #fff;","size":14,"color":"#fff","is_bold":false,"is_italic":false,"is_underline":false},"bg_color":""},"phone_page_header":{"img":{"filePath":"/statics/editor/phone/default/start_page.png"}}},"dispOptConsList":[],"extra_condition":{},"optionOrderRefs":[],"desc_common_page":{"font":{"css":"font-size: 16px;color: #303133;","size":16,"color":"#303133","is_bold":true,"is_italic":false,"is_underline":false},"show":true,"language":"zh_CN","theme_style":{"color":"rgba(38, 114, 255, 1)","colorMode":1},"hide_pre_btn":false,"showCustomCid":true,"hide_order_number":false,"hide_progress_bar":false,"showNumberByOrder":false},"defaultOptionList":[],"one_question_on_page":false,"hide_descriptor_number":true,"desc_question_page_default":{"logo":{"img":{"logo_scale":100},"position":"left"},"bg_img":{"img":{},"type":"img","color":"#303133","fillStyle":"fill","base_color":"#fff"},"option":{"font":{"css":"font-size: 16px;color: #606266;","size":14,"color":"#606266","is_bold":false,"is_italic":false,"is_underline":false}},"question":{"font":{"css":"font-size: 16px;color: #303133;","size":16,"color":"#303133","is_bold":false,"is_italic":false,"is_underline":false}},"phone_logo":{"img":{"logo_scale":100},"position":"left"},"submit_btn":{"font":{"css":"font-size: 16px;color: #fff;","size":14,"color":"#fff","is_bold":false,"is_italic":false,"is_underline":false},"text":"","bg_color":""},"page_header":{"img":{"filePath":"/statics/editor/pc/default/header_bg.png"}},"phone_bg_img":{"img":{},"type":"img","color":"#fff","fillStyle":"fill","base_color":"#fff"},"phone_option":{"font":{"css":"font-size: 16px;color: #606266;","size":14,"color":"#606266","is_bold":false,"is_italic":false,"is_underline":false}},"footer_content":"","phone_question":{"font":{"css":"font-size: 16px;color: #303133;","size":16,"color":"#303133","is_bold":false,"is_italic":false,"is_underline":false}},"phone_submit_btn":{"font":{"css":"font-size: 16px;color: #fff;","size":14,"color":"#fff","is_bold":false,"is_italic":false,"is_underline":false},"text":"","bg_color":""},"phone_page_header":{"img":{"filePath":"/statics/editor/phone/default/header_bg.png"}}}}}
     * {"code": 0, "data": {"id": "63214e263e2c0c000878b3d8"}}
     *
     * @param id
     * @param param
     * @return com.bestcem.xm.common.core.domain.web.XmResultJson<com.bestcem.xm.qdes.controller.vo.OnlyIdVo>
     * @author chenglong.yue <chenglong.yue@idiaoyan.com>
     * @date 2022/9/21 15:11
     */
    @ApiOperation(value = "更新问卷结构")
    @PutMapping("/{id:[a-fA-F0-9]{24}}")
    public XmResultJson<OnlyIdVo> updateQstruct(@PathVariable String id, @RequestBody JSONObject param) {
        log.info("updateQstruct qstructid:{},bodyparam:{}", id, param.toJSONString());
        if (!param.containsKey(DATA)) {
            return XmResultJson.fail(PARAM_LOST, "参数不合法，没有data");
        }
        QdesQstruct struct = questionService.checkAndGetQstruct(id);
        QdesProject project = questionService.checkAndGetProject(struct);

        questionService.updateQstruct(struct, project, param);
        OnlyIdVo ret = new OnlyIdVo();
        ret.setId(id);
        return XmResultJson.success(ret);
    }

    @ApiOperation(value = "查看发布记录")
    @GetMapping("/")
    public XmResultJson<List<QstructsDetailVo>> getPublishRecord(@XmGet GetPublishRecordParam param) {
        return XmResultJson.success(qstructService.getPublishRecord(param));
    }
}
